﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Birkelund.QueryStrings.Tokens;
using Birkelund.QueryStrings;

namespace Birkelund.QueryStrings.Test.IntegrationTests
{
    public class ChecksumCalculatorTest
    {
        [TearDown]
        public void Cleanup()
        {
            QueryStringConfiguration.Instance.ChecksumCalculator = ChecksumCalculators.Basic;
        }

        [Test]
        public void ChecksumCalculator_UseCustom()
        {
            Uri initialUrl = new Uri(@"http://localhost/test/testFile.aspx");
            var a = new ValueTypeToken<int>("a") { ExceptionNotificationBehaviour = ExceptionNotificationBehaviour.ThrowException };
            var b = new StringToken("b") { ExceptionNotificationBehaviour = ExceptionNotificationBehaviour.Silent };

            QueryStringConfiguration.Instance.ChecksumCalculator = ChecksumCalculators.Hash;
            int orgValue = 123;

            IUriWriter writer = UriWriter.CreateFromUri(initialUrl);
            writer.SetToken(a, orgValue);
            writer.SetToken(b, "abc"); //this token is not used actively in the test - used to simulate more tokens
            writer.ApplyCheckSumControl = true;
            writer.GenerateQueryAsString();

            #region Success scenario with checksum
            Uri validUri = writer.GenerateQueryAsUri();
            int validRead = a.ReadValue(validUri, ReadValueMode.CheckSumControl);
            Assert.AreEqual(orgValue, validRead);
            #endregion

            int manipulatedValue = 1234;
            writer.SetToken(a, manipulatedValue); //Simulate that a user has manipulated the uri
            Uri manipulatedUri = writer.GenerateQueryAsUri();

            #region Error scenario with checksum
            TokenParserException exception = Assert.Throws<TokenParserException>(() => a.ReadValue(manipulatedUri, ReadValueMode.CheckSumControl));
            Assert.AreEqual(FailureReason.CheckSumError, exception.FailureArgs.Reason);
            #endregion

            #region Success scenario with no checksum
            int validRead2 = a.ReadValue(manipulatedUri, ReadValueMode.NoCheckSumControl);
            Assert.AreEqual(manipulatedValue, validRead2);
            #endregion
        }
    }
}